package chatserver.netio;




import chatserver.tools.ChatException;
import chatserver.netio.ClientAttr;
import java.io.*;
import java.util.Enumeration;
import java.util.Vector;

public class AttrList {

    public AttrList() {
        this(new Vector());
    }

    private AttrList(Vector vector) {
        list = vector;
        oldBytes = new byte[0];
        newIndex = 0;
    }

    private AttrList(Attr attr, byte abyte0[])
            throws ChatException {
        list = new Vector();
        int j;
        for (int i = 0; i < abyte0.length; i += j) {
            byte byte0 = abyte0[i++];
            j = 0;
            int l = 0;
            int k;
            do {
                k = abyte0[i++] & 0xff;
                j |= (k & 0x7f) << l;
                l += 7;
            } while ((k & 0x80) != 0);
            list.addElement(attr.clone(byte0, abyte0, i, j));
        }

        oldBytes = abyte0;
        newIndex = list.size();
    }

    public AttrList(Attr attr, InputStream inputstream)
            throws ChatException, IOException {
        this(attr, inputstream, 0x200000);
    }

    public AttrList(Attr attr, InputStream inputstream, int i)
            throws ChatException, IOException {
        this(attr, readBytesFromInputStream(inputstream, i));
    }

    private static byte[] readBytesFromInputStream(InputStream inputstream, int i)
            throws ChatException, IOException {
        int j = readLength(inputstream);
        if (j > i) {
            throw new ChatException();
        }
        byte abyte0[] = new byte[j];
        int k;
        for (; j > 0; j -= k) {
            k = inputstream.read(abyte0, abyte0.length - j, j);
            if (k == -1) {
                throw new EOFException();
            }
        }

        return abyte0;
    }

    public void write(OutputStream outputstream)
            throws ChatException, IOException {
        byte abyte0[] = getNewBytes();
        writeLength(outputstream, oldBytes.length + abyte0.length);
        outputstream.write(oldBytes);
        outputstream.write(abyte0);
    }

    public void invalidateCache() {
        if (newIndex > 0) {
            oldBytes = new byte[0];
            newIndex = 0;
        }
    }

    private byte[] getNewBytes()
            throws ChatException {
        try {
            ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
            DataOutputStream dataoutputstream = new DataOutputStream(bytearrayoutputstream);
            Enumeration enumeration = list.elements();
            for (int i = 0; i < newIndex; i++) {
                enumeration.nextElement();
            }

            for (; enumeration.hasMoreElements(); write(dataoutputstream, (Attr) enumeration.nextElement())) {}
            return bytearrayoutputstream.toByteArray();
        } catch (IOException ioexception) {
            throw new ChatException(ioexception.toString());
        }
    }

    public void add(Attr attr)
            throws ChatException {
        list.addElement(attr);
    }

    private static int readLength(InputStream inputstream)
            throws IOException {
        int i = 0;
        int k = 0;
        int j;
        do {
            j = inputstream.read() & 0xff;
            i |= (j & 0x7f) << k;
            k += 7;
        } while ((j & 0x80) != 0);
        return i;
    }

    private static void writeLength(OutputStream outputstream, int i)
            throws IOException {
        do {
            int j = i & 0x7f;
            i >>= 7;
            if (i != 0) {
                j |= 0x80;
            }
            outputstream.write(j);
        } while (i != 0);
    }

    private void write(DataOutputStream dataoutputstream, Attr attr)
            throws IOException {
        byte abyte0[] = attr.getValue();
        dataoutputstream.write(attr.getId() & 0xff);
        writeLength(dataoutputstream, abyte0.length);
        dataoutputstream.write(abyte0);
    }

    public Enumeration getEnumeration() {
        return list.elements();
    }

    public Attr get(byte byte0) {
        return get(byte0, 0);
    }

    public Attr get(byte byte0, int i) {
        for (Enumeration enumeration = getEnumeration(); enumeration.hasMoreElements();) {
            Attr attr = (Attr) enumeration.nextElement();
            if (attr.getId() == byte0 && i-- == 0) {
                return attr;
            }
        }

        return null;
    }

    public void set(Attr attr)
            throws ChatException {
        byte byte0 = attr.getId();
        for (int i = 0; i < list.size(); i++) {
            Attr attr1 = (Attr) list.elementAt(i);
            if (attr1.getId() == byte0) {
                if (attr != null) {
                    list.setElementAt(attr, i);
                    invalidateCache();
                    attr = null;
                } else {
                    list.removeElementAt(i);
                    invalidateCache();
                    i--;
                }
            }
        }

        if (attr != null) {
            add(attr);
        }
    }

    public void set(byte byte0, Attr aattr[])
            throws ChatException {
        remove(byte0);
        for (int i = 0; i < aattr.length; i++) {
            add(aattr[i]);
        }

    }

    public void remove(byte byte0) {
        for (int i = 0; i < list.size(); i++) {
            Attr attr = (Attr) list.elementAt(i);
            if (attr.getId() == byte0) {
                list.removeElementAt(i);
                invalidateCache();
                i--;
            }
        }

    }

    public Object[] toArray() {
        Attr aattr[] = new Attr[list.size()];
        list.copyInto(aattr);
        return aattr;
    }

    public Vector toVector(byte byte0) {
        Vector vector = new Vector();
        for (Enumeration enumeration = getEnumeration(); enumeration.hasMoreElements();) {
            Attr attr = (Attr) enumeration.nextElement();
            if (attr.getId() == byte0) {
                vector.addElement(attr);
            }
        }

        return vector;
    }
    
    
    public void safeAddClientAttr(byte attrId, String value)
    {
        try {
            list.add(new ClientAttr(attrId, value));
        } catch (ChatException ex) {
        }
    }
    
    public void safeAddClientAttr(byte attrId, int value)
    {
        try {
            list.add(new ClientAttr(attrId, value));
        } catch (ChatException ex) {
        }
    }
        
     
    public void safeAddClientAttr(byte attrId, byte[] value)
    {
        list.add(new ClientAttr(attrId, value));
    }   

    public Attr[] toArray(byte byte0) {
        Vector vector = toVector(byte0);
        Attr aattr[] = new Attr[vector.size()];
        vector.copyInto(aattr);
        return aattr;
    }

    public AttrList(Attr attr, Reader reader)
            throws ChatException, IOException {
        this();
        char c;
        do {
            Attr attr1;
            try {
                attr1 = (Attr) attr.clone();
            } catch (Exception exception) {
                attr1 = null;
            }
            do {
                reader.mark(1);
                c = (char) reader.read();
                if (c == '\n') {
                    reader.reset();
                    return;
                }
            } while (Character.isWhitespace(c));
            reader.reset();
            attr1.read(reader);
            list.addElement(attr1);
            do {
                reader.mark(1);
                c = (char) reader.read();
            } while (c != '\n' && Character.isWhitespace(c));
        } while (c == ',');
        reader.reset();
    }

    @Override
    public String toString() {
        StringBuilder stringbuffer = new StringBuilder();
        boolean flag = true;
        for (Enumeration enumeration = list.elements(); enumeration.hasMoreElements(); stringbuffer.append(enumeration.nextElement())) {
            if (flag) {
                flag = false;
            } else {
                stringbuffer.append(", ");
            }
        }

        return stringbuffer.toString();
    }

    @Override
    public Object clone() {
        return new AttrList((Vector) list.clone());
    }
    
    private static final int MAXSIZE = 0x200000;
    
    private Vector list;
    private byte oldBytes[];
    private int newIndex;
}
